using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR;
using System.Security.Claims;

namespace SumerCoreDevOps.ControlApi.Hubs;

/// <summary>
/// DevOps实时通信Hub
/// 提供实时日志流、任务状态更新、节点状态更新等功能
/// </summary>
[Authorize]
public class DevOpsHub : Hub
{
    private readonly ILogger<DevOpsHub> _logger;
    private static readonly HashSet<string> _connectedUsers = new();

    public DevOpsHub(ILogger<DevOpsHub> logger)
    {
        _logger = logger;
    }

    /// <summary>
    /// 客户端连接时触发
    /// </summary>
    public override async Task OnConnectedAsync()
    {
        var username = Context.User?.FindFirst(ClaimTypes.Name)?.Value ?? "Anonymous";
        var connectionId = Context.ConnectionId;

        _connectedUsers.Add(connectionId);
        _logger.LogInformation("用户 {Username} 已连接 WebSocket，ConnectionId: {ConnectionId}",
            username, connectionId);

        await base.OnConnectedAsync();
    }

    /// <summary>
    /// 客户端断开连接时触发
    /// </summary>
    public override async Task OnDisconnectedAsync(Exception? exception)
    {
        var username = Context.User?.FindFirst(ClaimTypes.Name)?.Value ?? "Anonymous";
        var connectionId = Context.ConnectionId;

        _connectedUsers.Remove(connectionId);

        if (exception != null)
        {
            _logger.LogError(exception, "用户 {Username} 断开连接时发生错误，ConnectionId: {ConnectionId}",
                username, connectionId);
        }
        else
        {
            _logger.LogInformation("用户 {Username} 已断开 WebSocket，ConnectionId: {ConnectionId}",
                username, connectionId);
        }

        await base.OnDisconnectedAsync(exception);
    }

    // ======================================
    // 订阅方法（客户端调用）
    // ======================================

    /// <summary>
    /// 订阅任务日志流
    /// </summary>
    /// <param name="taskId">任务ID</param>
    public async Task SubscribeTaskLogs(long taskId)
    {
        var groupName = $"task-logs-{taskId}";
        await Groups.AddToGroupAsync(Context.ConnectionId, groupName);
        _logger.LogInformation("ConnectionId {ConnectionId} 订阅任务日志: {TaskId}",
            Context.ConnectionId, taskId);
    }

    /// <summary>
    /// 取消订阅任务日志流
    /// </summary>
    /// <param name="taskId">任务ID</param>
    public async Task UnsubscribeTaskLogs(long taskId)
    {
        var groupName = $"task-logs-{taskId}";
        await Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);
        _logger.LogInformation("ConnectionId {ConnectionId} 取消订阅任务日志: {TaskId}",
            Context.ConnectionId, taskId);
    }

    /// <summary>
    /// 订阅任务状态更新
    /// </summary>
    /// <param name="pipelineInstanceId">流水线实例ID</param>
    public async Task SubscribeTaskStatus(long pipelineInstanceId)
    {
        var groupName = $"task-status-{pipelineInstanceId}";
        await Groups.AddToGroupAsync(Context.ConnectionId, groupName);
        _logger.LogInformation("ConnectionId {ConnectionId} 订阅任务状态: {InstanceId}",
            Context.ConnectionId, pipelineInstanceId);
    }

    /// <summary>
    /// 取消订阅任务状态更新
    /// </summary>
    /// <param name="pipelineInstanceId">流水线实例ID</param>
    public async Task UnsubscribeTaskStatus(long pipelineInstanceId)
    {
        var groupName = $"task-status-{pipelineInstanceId}";
        await Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);
        _logger.LogInformation("ConnectionId {ConnectionId} 取消订阅任务状态: {InstanceId}",
            Context.ConnectionId, pipelineInstanceId);
    }

    /// <summary>
    /// 订阅节点状态更新
    /// </summary>
    public async Task SubscribeNodeStatus()
    {
        const string groupName = "node-status";
        await Groups.AddToGroupAsync(Context.ConnectionId, groupName);
        _logger.LogInformation("ConnectionId {ConnectionId} 订阅节点状态", Context.ConnectionId);
    }

    /// <summary>
    /// 取消订阅节点状态更新
    /// </summary>
    public async Task UnsubscribeNodeStatus()
    {
        const string groupName = "node-status";
        await Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);
        _logger.LogInformation("ConnectionId {ConnectionId} 取消订阅节点状态", Context.ConnectionId);
    }

    /// <summary>
    /// 订阅流水线实例的所有更新（日志+状态）
    /// </summary>
    /// <param name="pipelineInstanceId">流水线实例ID</param>
    public async Task SubscribePipelineInstance(long pipelineInstanceId)
    {
        var groupName = $"pipeline-instance-{pipelineInstanceId}";
        await Groups.AddToGroupAsync(Context.ConnectionId, groupName);
        _logger.LogInformation("ConnectionId {ConnectionId} 订阅流水线实例: {InstanceId}",
            Context.ConnectionId, pipelineInstanceId);
    }

    /// <summary>
    /// 取消订阅流水线实例的所有更新
    /// </summary>
    /// <param name="pipelineInstanceId">流水线实例ID</param>
    public async Task UnsubscribePipelineInstance(long pipelineInstanceId)
    {
        var groupName = $"pipeline-instance-{pipelineInstanceId}";
        await Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);
        _logger.LogInformation("ConnectionId {ConnectionId} 取消订阅流水线实例: {InstanceId}",
            Context.ConnectionId, pipelineInstanceId);
    }

    // ======================================
    // 服务端推送方法（由后端服务调用）
    // 这些方法不应该被客户端直接调用
    // ======================================

    // 注意：这些方法通过 IHubContext<DevOpsHub> 在服务中调用
    // 例如：await _hubContext.Clients.Group($"task-logs-{taskId}").SendAsync("ReceiveTaskLog", logData);
}
